package com.briup.model.service.impl;

import com.briup.common.exception.CustomerException;
import com.briup.common.util.PageResult;
import com.briup.common.web.MessageStatus;
import com.briup.common.web.SecurityUtil;
import com.briup.model.entity.Model;
import com.briup.model.entity.extend.EvaluateEx;
import com.briup.model.entity.extend.TraningEx;
import com.briup.model.mapper.ModelMapper;
import com.briup.model.mapper.extend.ModelExtendMapper;
import com.briup.model.service.IModelService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 模型业务实现类
 */
@Service
public class ModelServiceImpl implements IModelService {
    @Autowired
    private ModelMapper modelMapper;
    @Autowired
    private ModelExtendMapper modelExtendMapper;

    // 插入模型
    @Transactional
    @Override
    public void insertModel(Model model) {
        Model modelFromDB = modelExtendMapper.findByName(model.getModelName());
        // 如果模型名称已存在,不能添加
        if(modelFromDB != null){
            throw new CustomerException(MessageStatus.DATA_EXISTED);
        }
        // 填充模型中额外字段(accuracyRate不填)
        model.setTaskId("1"); //  TODO此字段暂未知用途,需要携带给python
        model.setModelTime(new Date()); // 训练时间
        model.setReleaseVersion("V1");// 发布版本
        model.setTrainingStatus(1); //训练状态 1:未训练
        model.setModelStatus(1); // 模型状态 1:未发布
        model.setUserId(Integer.parseInt(SecurityUtil.getUserId()));
        model.setUserName(SecurityUtil.getUsername());
        // 插入模型
        modelMapper.insert(model);
    }

    // 查找简单模型
    @Override
    public List<Model> findModel() {
        return modelExtendMapper.findAll();
    }

    // 根据模型id和模型训练版本查看模型训练相关和模型评估相关等信息
    @Override
    public Map<String, Object> findModelExByIdAndVersion(Integer modelId, String modelVersion) {
        // 封装的模型训练拓展类和模型评估拓展类
        Map<String,Object> traningExAndEvaluateEx = new HashMap<>();

        // 1.封装训练拓展类(训练版本记录以及训练结果)
        TraningEx traningEx = modelExtendMapper.findTraningExByModelIdAndVersion(modelId,modelVersion);
        // 此处暂时预防查询已删除的模型
        if(traningEx == null){
            throw new CustomerException("模型不可用");
        }
        // 2.封装的评估拓展类(评估记录以及评估结果以及评估错误) 一个训练可以评估多次
        List<EvaluateEx> evaluateExList = modelExtendMapper.findEvaluateExByTraningId(traningEx.getId());

        traningExAndEvaluateEx.put("traningEx",traningEx);
        traningExAndEvaluateEx.put("evaluateExList",evaluateExList);
        return traningExAndEvaluateEx;
    }
    // 删除模型
    @Transactional
    @Override
    public void deleteModel(Integer id) {
        Model model = new Model();
        model.setId(id);
        model.setModelStatus(5); // 暂时5代表模型删除不可用
        modelMapper.updateByPrimaryKeySelective(model);
    }

    @Override
    public Map<String, Object> modelInfo(Integer id) {
        // 封装含有模型,训练拓展,评估拓展的map
        Map<String,Object> modelWithTrainExAndEvaluateEx = new HashMap<>();
        // 1.封装模型信息
        Model model = modelMapper.selectByPrimaryKey(id);
        if(model.getTrainingStatus() != 1){
            // ==1 状态是未训练,没有训练信息
            // 2.封装训练拓展
            // 查出该模型下的训练记录
            List<TraningEx> traningExList = modelExtendMapper.findTraningExByModelId(id);
            // 只取最新训练版本记录
            TraningEx traningEx = traningExList.get(traningExList.size() - 1);
            // 3.封装评估拓展
            List<EvaluateEx> evaluateExList = modelExtendMapper.findEvaluateExByTraningId(traningEx.getId());

            modelWithTrainExAndEvaluateEx.put("traningEx",traningEx);
            modelWithTrainExAndEvaluateEx.put("evaluateExList",evaluateExList);
        }
        // 基本模型信息
        modelWithTrainExAndEvaluateEx.put("model",model);

        return modelWithTrainExAndEvaluateEx;
    }
    // 条件查询模型
    @Override
    public PageResult<Model> findModelByCondition(Model model, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        Page<Model> modelPage = modelExtendMapper.findModelByCondition(model);
        return new PageResult<Model>(modelPage.getTotal(),modelPage.getResult());
    }

}
